﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace VIT.Pre
{
    internal class WSEnumerator : System.Collections.IEnumerator
    {
        private WSEnumerableDelegate _action;
        private System.Collections.IEnumerable _source;
        private int _cursor;
        private int _cursorPart;
        private int _bufferSizeService;
        private int _count;

        public WSEnumerator(WSEnumerableDelegate action, int bufferSizeService = 10, int count = -1)
        {
            _action = action;
            _cursor = -1;
            _cursorPart = -1;
            _bufferSizeService = bufferSizeService;
            _count = count;
            if (_count == -1)
            {
                _action(0, _bufferSizeService, ref _count);
            }
        }

        object System.Collections.IEnumerator.Current
        {
            get
            {
                if (_cursor < 0 || _cursor == _count) throw new InvalidOperationException("Not Start!");
                if (_cursorPart != _cursor / _bufferSizeService)
                {
                    _cursorPart = _cursor / _bufferSizeService;
                    int tmpCount = 0;
                    _source = _action(_cursorPart * _bufferSizeService, _bufferSizeService, ref tmpCount);
                }
                long index = _cursor % _bufferSizeService;
                return _source.Cast<object>().ToArray()[index];
            }
        }

        bool System.Collections.IEnumerator.MoveNext()
        {
            if (_cursor < _count) _cursor++;
            return !(_cursor == _count);
        }

        void System.Collections.IEnumerator.Reset()
        {
            _cursor = -1;
        }
    }

    public delegate System.Collections.IEnumerable WSEnumerableDelegate(int skip, int take, ref int count);
}